<template>
  <el-space direction="vertical" fill class="menu-check">
    <div class="menu-check__header">
      <el-input v-model="keyword" placeholder="输入关键字进行过滤" />
    </div>

    <el-scrollbar class="menu-check__body" height="200">
      <el-tree
        ref="treeRef"
        :data="treeData"
        :props="defaultProps"
        :filter-node-method="filterNode"
        node-key="id"
        show-checkbox
        default-expand-all
        @check="handleChange"
      />
    </el-scrollbar>

    <!-- <el-button @click="fn1">获取当前勾选的 菜单Id 集合</el-button> -->

    <!-- <el-button @click="fn2">设置当前勾选的 菜单Id 集合</el-button> -->
  </el-space>
</template>

<script>
import { getMenuListAll } from "@/api/system";
import { deepTree } from "@/utils/common";

export default {
  name: "MenuCheck",

  props: {
    modelValue: {
      type: Array,
      default: () => [],
    },
  },

  emits: ["update:modelValue"],

  data() {
    return {
      keyword: "", // 搜索关键字
      list: [],
      defaultProps: {
        label: "name",
        // children: "children",
      },
    };
  },

  computed: {
    treeData() {
      return deepTree(this.list);
    },
  },

  watch: {
    modelValue: {
      handler() {
        this.set();
      },
      deep: true,
      immediate: true,
    },

    list: {
      handler() {
        this.set();
      },
      immediate: true,
    },

    keyword(newVal) {
      this.$refs.treeRef.filter(newVal);
    },
  },

  methods: {
    /**
     * 过滤节点的函数
     *    触发时机: 当我们执行 Tree 组件实例的 filter() 方法时
     *
     *    参数:
     *        1. value - 调用 Tree实例的 filter() 时传递过来的参数
     *        2. node  - 当前节点数据
     *    返回值:
     *        true     - 当前节点显示
     *        false    - 当前节点隐藏
     */
    filterNode(value, node) {
      // console.log("filterNode value", value);
      // console.log("filterNode node", node);
      return node.name.includes(value);
    },

    /**
     * 是否为叶子节点
     * @param {*} id 节点Id
     * @returns {boolean}
     */
    isLeaf(id) {
      const tmp = this.list.find((item) => item.parentId === id);
      return !tmp;
    },

    /**
     * 设置勾选
     */
    set() {
      // 1. 过滤出叶子节点
      const keys = this.modelValue.filter((item) => this.isLeaf(item));
      // 2. 设置
      this.$refs.treeRef?.setCheckedKeys(keys);
    },

    /**
     * el-tree 勾选时触发
     * @param {*} node 当前节点
     * @param {*} checkedKeys 勾选的节点Id集合
     * @param {*} halfCheckedKeys 半勾选的节点Id集合
     */
    handleChange(node, { checkedKeys, halfCheckedKeys }) {
      // 组装 checkedKeys 与 halfCheckedKeys
      const tmp = [...checkedKeys, ...halfCheckedKeys];
      this.$emit("update:modelValue", tmp);
    },

    async refresh() {
      try {
        const result = await getMenuListAll();
        // console.log("result", result);
        this.list = result;
      } finally {
        // ...
      }
    },

    // fn1() {
    //   // 获取勾选的
    //   const checkedKeys = this.$refs.treeRef.getCheckedKeys();
    //   // 获取半勾选的
    //   const halfCheckedKeys = this.$refs.treeRef.getHalfCheckedKeys();
    //   console.log("checkedKeys", checkedKeys);
    //   console.log("halfCheckedKeys", halfCheckedKeys);
    // },

    // fn2() {

    //   /**
    //    * 后端返回数据是 [1, 2, 4] 使用下面方面会把Id为3的也给勾选，这是不对的。如何解决？？？
    //    *
    //    * 思考
    //    *    [1, 2, 4] => [2, 4]
    //    *    [5, 7, 14] => [14]
    //    *
    //    * 叶子节点：没有子级的节点
    //    *
    //    * 过滤出属于叶子节点的Id
    //    */
    //   // const ids = [5, 7, 14].filter((item) => this.isLeaf(item));
    //   // console.log("ids", ids);

    //   // this.$refs.treeRef.setCheckedKeys(ids);
    // },
  },

  created() {
    this.refresh();
  },
};
</script>

<style lang="scss" scoped>
.menu-check {
  display: flex;
  width: 100%;

  &__body {
    padding: 10px;
    box-shadow: 0 0 0 1px #dcdfe6 inset;
    border-radius: 4px;
  }
}
</style>
